package com.ipoint.icompany.service;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.log.Log;

import com.ipoint.icompany.model.Day;
import com.ipoint.icompany.model.Person;
import com.ipoint.icompany.model.Project;
import com.ipoint.icompany.model.ReportForWorkingDay;
import com.ipoint.icompany.model.WorkingDay;
import com.ipoint.icompany.model.WorkingDayOnProject;

@Name("reportForWorkingDayService")
@Scope(ScopeType.PAGE)
public class ReportForWorkingDayService {
	@In
	private EntityManager entityManager;

	@In(create = true)
	private ProjectService projectService;

	@In(required = false, value = Person.CURRENT_PERSON)
	private Person currentPerson;

	@In(required = false)
	@Out
	private ReportForWorkingDay report;

	@Logger
	private Log log;

	public ReportForWorkingDay getReport() {
		return report;
	}

	public void setReport(ReportForWorkingDay report) {
		this.report = report;
	}

	public void generateReport() {
		report = new ReportForWorkingDay();
		WorkingDay workingDay = new WorkingDay();
		workingDay.setDay(getCurrentDay());
		report.setWorkingDay(workingDay);
		report.getWorkingDay().setPerson(currentPerson);
		Map<Long, WorkingDayOnProject> workingDayOnProjectMap = new HashMap<Long, WorkingDayOnProject>();
		for (Project project : projectService.getProjectList()) {
			WorkingDayOnProject workingDayOnProject = new WorkingDayOnProject();
			workingDayOnProject.setProject(project);
			workingDayOnProject.setWorkingDay(report.getWorkingDay());
			workingDayOnProjectMap.put(project.getId(), workingDayOnProject);
		}
		report.setWorkingDayOnProjectMap(workingDayOnProjectMap);
	}

	public Day getCurrentDay() {
		Calendar calendar = GregorianCalendar.getInstance();
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		Day result = new Day();
		result.setDate(calendar.getTime());
		return result;
	}

	@Transactional
	public void create() {
		Day day = null;
		try {
			day = findDay(report.getWorkingDay().getDay().getDate());
		} catch (NoResultException e) {
			log.error("Error getting day to date: "
					+ report.getWorkingDay().getDay().getDate()
					+ ". Recomended restarted server.", e);
			return;
		}
		report.getWorkingDay().setDay(day);
		report.getWorkingDay().setWorkingDayOnProjectSet(
				new HashSet<WorkingDayOnProject>());
		for (WorkingDayOnProject workingDayOnProject : report
				.getWorkingDayOnProjectMap().values()) {
			if (workingDayOnProject.getDescription() != null
					&& !"".equals(workingDayOnProject.getDescription())) {
				report.getWorkingDay().getWorkingDayOnProjectSet().add(
						workingDayOnProject);
			}
		}
		entityManager.persist(report.getWorkingDay());
	}

	private Day findDay(Date date) {
		return (Day) entityManager.createQuery(
				"from Day d where d.date = :date").setParameter("date", date)
				.getSingleResult();
	}
}
